package com.jfinal.ext.ueditor.controller;

import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.core.Controller;
import com.jfinal.core.Path;
import com.jfinal.ext.interceptor.GET;
import com.jfinal.ext.interceptor.POST;
import com.jfinal.ext.ueditor.config.FileUploadConfig;
import com.jfinal.ext.ueditor.config.IUploadConfig;
import com.jfinal.ext.ueditor.config.ImageUploadConfig;
import com.jfinal.ext.ueditor.config.UeditorConfig;
import com.jfinal.ext.ueditor.result.CatchImageResult;
import com.jfinal.ext.ueditor.result.ListResult;
import com.jfinal.ext.ueditor.service.UeditorService;
import com.jfinal.ext.util.FormatUtil;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.StrKit;
import com.jfinal.upload.UploadFile;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;

/**
 * @author 江理_网猿 (timor)
 * @date 2020/10/23 0023
 */
@Path("/api/ueditor-plus")
public class UeditorPlusController extends Controller {
    private static final String TEMP_UPLOAD_PATH = "/temp/{yyyy}-{MM}-{dd}";

    @Inject
    private UeditorService service;
    @Inject
    private UeditorConfig config;

    /**
     * ueditor上传文件配置信息
     */
    @Before(GET.class)
    public void config() {
        renderJson(config.toJsonString());
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    /**
     * 上传图片
     */
    @Before(POST.class)
    public void uploadImage() {
        final ImageUploadConfig uploadConfig = config.getImageUploadConfig();
        final UploadFile uploadFile = getUploadFile(uploadConfig);

        renderJson(service.uploadImage(uploadFile, uploadConfig));
    }

    /**
     * 上传涂鸦图片，图片为base64编码
     * Content-Type：application/x-www-form-urlencoded
     */
    @Before(POST.class)
    public void uploadScrawl() {
        final ImageUploadConfig uploadConfig = config.getScrawlUploadConfig();
        final String scrawl = getPara(uploadConfig.getFieldName());

        renderJson(service.uploadScrawl(scrawl, uploadConfig));
    }

    /**
     * 上传截图
     */
    @Before(POST.class)
    public void uploadScreenshot() {
        renderJson(service.uploadScreenshot());
    }


    /**
     * 上传视频
     */
    @Before(POST.class)
    public void uploadVideo() {
        final FileUploadConfig uploadConfig = config.getVideoUploadConfig();
        final UploadFile uploadFile = getUploadFile(uploadConfig);

        renderJson(service.uploadVideo(uploadFile, uploadConfig));
    }

    /**
     * 上传音频
     */
    @Before(POST.class)
    public void uploadAudio() {
        renderJson(service.uploadAudio());
    }

    /**
     * 上传文件
     */
    @Before(POST.class)
    public void uploadFile() {
        final FileUploadConfig uploadConfig = config.getFileUploadConfig();
        final UploadFile uploadFile = getUploadFile(uploadConfig);

        renderJson(service.uploadFile(uploadFile, uploadConfig));
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    /**
     * 列出图片
     *
     * @param start 开始位置，从0开始
     * @param size  大小
     */
    @Before(GET.class)
    public void listImage(int start, int size) {
        renderJson(service.listImage(start, size, config.getImageManagerConfig()));
    }

    /**
     * 列出文件
     *
     * @param start 开始位置，从0开始
     * @param size  大小
     */
    @Before(GET.class)
    public void listFile(int start, int size) {
        renderJson(service.listFile(start, size, config.getFileManagerConfig()));
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    /**
     * 远程抓取图片，参数：source[]
     */
    @Before(POST.class)
    public void catchImage(String callback) {
        if (StrKit.notBlank(callback) && !validCallbackName(callback)) {
            renderJson(new ListResult<>("callback name is invalid"));
            return;
        }


        final String[] sources = getParaValues("source[]");

        if (null == sources) {
            renderJson(new ListResult<>("缺少source[]参数！"));
            return;
        }


        final ListResult<CatchImageResult> result = service.catchImage(
                Arrays.asList(sources), config.getCatcherUploadConfig());

        if (StrKit.isBlank(callback)) {
            renderJson(result);
            return;
        }

        renderJavascript("%s(%s)".formatted(callback, JsonKit.toJson(result)));
    }

    private boolean validCallbackName(String name) {
        final String callbackNamePatten = "^[a-zA-Z_]+\\w*$";

        return name.matches(callbackNamePatten);
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    private UploadFile getUploadFile(@NotNull IUploadConfig config) {
        return getFile(
                config.getFieldName(),
                getTempFilePath(),
                config.getMaxSize());
    }

    private String getTempFilePath() {
        return FormatUtil.parse(TEMP_UPLOAD_PATH);
    }

}
